﻿#ifndef __TWAINCPP_
#define __TWAINCPP_

#include "twain.h"
#include <QDebug>
#pragma execution_character_set("utf-8")；

#define TWCPP_ANYCOUNT		(-1)
#define TWCPP_CANCELTHIS	(1)
#define TWCPP_CANCELALL		(2)
#define TWCPP_DOTRANSFER	(0)

class CTwain
{

public:

    CTwain(HWND hWnd = nullptr);
	virtual ~CTwain();
	bool InitTwain(HWND hWnd);
	void ReleaseTwain();

	/*  
    This routine must be implemented by the dervied class
    After setting the required values in the m_AppId structure,
    the derived class should call the parent class implementation
    Refer Pg: 51 of the Twain Specification version 1.8
    此例程必须由dervied类实现
    在m_AppId结构中设置所需的值后，
    派生类应该调用父类实现
    请参阅Twain规范1.8版的第51页
	*/

	virtual void GetIdentity();
	virtual bool SelectSource();
    virtual bool OpenSource(TW_IDENTITY *pSource = nullptr);
    virtual int  ShouldTransfer(TW_IMAGEINFO& info)
    {
        return TWCPP_DOTRANSFER;
    }
	
    bool ProcessMessage(MSG msg);

	bool SelectDefaultSource();
	bool IsValidDriver() const;
    bool SourceSelected() const
    {
        return m_bSourceSelected;
    }
	bool DSMOpen() const;
	bool DSOpen() const;
    bool SourceEnabled() const
    {
        return m_bSourceEnabled;
    }
    bool ModalUI() const
    {
        return m_bModalUI;
    }

    TW_INT16 GetRC() const
    {
        return m_returnCode;
    }
    TW_STATUS GetStatus() const
    {
        return m_Status;
    }

	bool SetImageCount(TW_INT16 nCount = 1);
    bool Acquire(int numImages,TW_UINT16 duplex,TW_UINT16 size,TW_UINT16 pixel,TW_UINT16 resolution);

public:
	bool CallTwainProc(pTW_IDENTITY pOrigin,pTW_IDENTITY pDest,
					   TW_UINT32 DG,TW_UINT16 DAT,TW_UINT16 MSG,
					   TW_MEMREF pData);

	void CloseDSM();
	void CloseDS();

	bool GetCapability(TW_CAPABILITY& twCap,TW_UINT16 cap,TW_UINT16 conType=TWON_DONTCARE16);
	bool GetCapability(TW_UINT16 cap,TW_UINT32& value);
	bool SetCapability(TW_UINT16 cap,TW_UINT16 value,bool sign=false);
	bool SetCapability(TW_CAPABILITY& twCap);
	bool EnableSource(bool showUI = true);

    bool SetResolution(TW_UINT16 cap,TW_UINT32 value);


	bool GetImageInfo(TW_IMAGEINFO& info);

	virtual bool DisableSource();

	void TransferImage();
	bool EndTransfer();
	void CancelTransfer();
	bool ShouldContinue();
	bool GetImage(TW_IMAGEINFO& info);
    void get_source_list();//获取所有数据源列表

	virtual void CopyImage(HANDLE hBitmap,TW_IMAGEINFO& info)=0;

public:
    HINSTANCE m_hTwainDLL;//是否已载入库
    DSMENTRYPROC m_pDSMProc;//数据源入口
    TW_USERINTERFACE twUI;

    TW_IDENTITY m_AppId;//应用程序
    TW_IDENTITY m_Source;//数据源
	TW_STATUS m_Status;
    TW_INT16  m_returnCode;//状态码
    HWND m_hMessageWnd;//消息窗口句柄

    bool m_bSourceSelected;//是否已选择数据源
    bool m_bDSMOpen;//是否已打开数据源管理器
    bool m_bDSOpen;//是否已打开数据源
    bool m_bSourceEnabled;//数据源是否设为可用
	bool m_bModalUI;

	int m_nImageCount;
    QList<TW_IDENTITY> sourcelist;//存放扫描源的链表
};

#endif
